package com.huadao.cart_ccs.experiment.preprocessing;

import com.huadao.cart_ccs.common.ParamsPreferences;
import com.huadao.cart_ccs.common.scheudle.ScheduleUtil;
import com.huadao.cart_ccs.data.bo.CO2BO;
import com.huadao.cart_ccs.data.bo.CommandWord;
import com.huadao.cart_ccs.data.bo.DoorBO;
import com.huadao.cart_ccs.data.bo.ElectronicScaleBO;
import com.huadao.cart_ccs.data.bo.LiquidLevelBO;
import com.huadao.cart_ccs.data.bo.O2BO;
import com.huadao.cart_ccs.data.bo.PeristalticPumpBO;
import com.huadao.cart_ccs.data.bo.TemperatureBO;
import com.huadao.cart_ccs.data.task.LiquidLoopTask;
import com.huadao.cart_ccs.modle.CO2Modle;
import com.huadao.cart_ccs.modle.CultureTankModle;
import com.huadao.cart_ccs.modle.DoorModle;
import com.huadao.cart_ccs.modle.ElectronicScaleModle;
import com.huadao.cart_ccs.modle.LiquidLevelModel;
import com.huadao.cart_ccs.modle.O2Modle;
import com.huadao.cart_ccs.modle.PeristalticPumpModle;
import com.huadao.cart_ccs.modle.PumpControlModle;
import com.huadao.cart_ccs.modle.TemperatureModle;
import com.huadao.cart_ccs.widget.MultiStateTextView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.Date;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

public class PreprocessingPresenter extends PreprocessingContract.IPreprocessingPresenter {


    private PumpControlModle pumpControlModle;

    private PeristalticPumpModle peristalticPumpModle;
    private LiquidLevelModel liquidLevelModel;
    private ElectronicScaleModle electronicScaleModle;
    private TemperatureModle temperatureModle;
    private CO2Modle co2Modle;
    private O2Modle o2Modle;
    private DoorModle doorModle;
    private CultureTankModle cultureTankModle;
    private LiquidLoopTask inputLiquidTask;
    private boolean isLiquidInputFinish;
    private Disposable checkDevice_disposable;
    private ScheduledFuture changeAirSchedule;
    private Date changeAirStartTime;
    private int changeAirTime = 30;//s
    private boolean isFirstWeight;

    public PreprocessingPresenter(PreprocessingContract.IPreprocessingView baseView) {
        attachView(baseView);
        EventBus.getDefault().register(this);
        peristalticPumpModle = new PeristalticPumpModle();
        pumpControlModle = new PumpControlModle();
        //        serialPortModle=new SerialPortModle();
        liquidLevelModel = new LiquidLevelModel();
        electronicScaleModle = new ElectronicScaleModle();
        temperatureModle = new TemperatureModle();
        co2Modle = new CO2Modle();
        o2Modle = new O2Modle();
        doorModle = new DoorModle();
        cultureTankModle = new CultureTankModle();
    }

    @Override
    public void checkAll() {
        baseView.showLoading("正在检测...");

        //读取 进液泵
        //读取 循环泵
        //读取 废液泵
        //读取 回收泵
        pumpControlModle.readFeedLiquorPump();
        pumpControlModle.readCirculatingPump();
        pumpControlModle.readWasteLiquorPump();
        pumpControlModle.readRecyclingPump();

        baseView.onCheckInputPump(MultiStateTextView.STATE_UNKNOWN);
        baseView.onCheckCiriclingPump(MultiStateTextView.STATE_UNKNOWN);
        baseView.onCheckWastePump(MultiStateTextView.STATE_UNKNOWN);

        baseView.onCheckReclaimPump(MultiStateTextView.STATE_UNKNOWN);
        checkCO2();
        baseView.onCheckCO2(MultiStateTextView.STATE_UNKNOWN);
        checkO2();
        baseView.onCheckO2(MultiStateTextView.STATE_UNKNOWN);
        checkTemperature();
        baseView.onCheckTemperature(MultiStateTextView.STATE_UNKNOWN);
        checkWeight();
        baseView.onCheckWeight(MultiStateTextView.STATE_UNKNOWN);
        checkLiquidLevelMeter();
        baseView.onCheckLiquidLevelMeter(MultiStateTextView.STATE_UNKNOWN);


        //5秒没有返回
        checkDevice_disposable = io.reactivex.Observable.timer(5, TimeUnit.SECONDS).subscribeOn(Schedulers.io())
                                                        .observeOn(AndroidSchedulers.mainThread())
                                                        .subscribe(new Consumer<Long>() {
                                                            @Override
                                                            public void accept(Long aLong) throws Exception {
                                                                baseView.summaryDeviceSelfCheck();
                                                                baseView.hideLoading();
                                                            }
                                                        });
    }


    @Override
    void checkFeedLiquorPump() {
        peristalticPumpModle.readFeedLiquorPump();
    }

    void checkPump() {
        peristalticPumpModle.readPeristaltic_pump();


    }

    @Override
    void checkLiquidLevelMeter() {
        liquidLevelModel.readLiquidLevel();
    }

    @Override
    void checkWeight() {
        electronicScaleModle.weight();
    }

    @Override
    void checkTemperature() {
        temperatureModle.readTemperature();
    }

    @Override
    void checkCO2() {
        co2Modle.readCO2();
    }

    @Override
    void checkO2() {
        o2Modle.readO2();
    }

    @Override
    void openDoor() {
        doorModle.open();
    }

    @Override
    void closeDoor() {
        doorModle.close();
    }

    @Override
    void readDoor() {
        doorModle.read();
    }

    @Override
    public void initPeel() {
        electronicScaleModle.peel(new byte[]{0, 0, 0, 0});
    }

    @Override
    void setCO2() {
        co2Modle.setCO2(ParamsPreferences.getInstance().getCO2());
    }

    @Override
    void setO2() {
        o2Modle.setO2(ParamsPreferences.getInstance().getO2());
    }

    @Override
    void setTemperature() {
        temperatureModle.setTemperature(ParamsPreferences.getInstance().getTemperature());
    }

    @Override
    public void openAirPump() {
        cultureTankModle.openMagneticStirrer(ParamsPreferences.getInstance().getCultureTankSpeed());
        changeAirStartTime = new Date();
        changeAirSchedule = ScheduleUtil.getInstance().schedule(new Runnable() {
            @Override
            public void run() {
                cultureTankModle.closeMagneticStirrer();
            }
        }, changeAirTime, TimeUnit.SECONDS);
    }

    @Override
    int getLeftChangeAirTime() {
        if (changeAirStartTime == null) {
            return 0;
        }
        Date now = new Date();
        int diffSecond = (int) ((now.getTime() - changeAirStartTime.getTime()) / 1000);
        int leftTime = changeAirTime - diffSecond;
        if (leftTime < 0) {
            leftTime = 0;
        }
        return leftTime;
    }

    @Override
    public void firstWeight() {
        isFirstWeight = true;
        electronicScaleModle.weight();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(PeristalticPumpBO event) {
        byte commondWord = event.getCommondWord();
        if (commondWord == CommandWord.readSucc[0] || commondWord == CommandWord.readFail[0]) {
            boolean isOK = commondWord == CommandWord.readSucc[0];
            int state = isOK ? MultiStateTextView.STATE_OK : MultiStateTextView.STATE_ERROR;
            if (event.getModularNO() == PeristalticPumpBO.PeristalticPump_fluidIntake) {
                baseView.onCheckInputPump(state);
            } else if (event.getModularNO() == PeristalticPumpBO.PeristalticPump_circulating) {
                baseView.onCheckCiriclingPump(state);
            } else if (event.getModularNO() == PeristalticPumpBO.PeristalticPump_waste) {
                baseView.onCheckWastePump(state);
            } else if (event.getModularNO() == PeristalticPumpBO.PeristalticPump_reclaim) {
                baseView.onCheckReclaimPump(state);
            }
        } else {
            baseView.showToast(event.toString());
            isLiquidInputFinish = false;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(LiquidLevelBO event) {
        if (event.getCommondWord() == CommandWord.readSucc[0]) {
            baseView.onCheckLiquidLevelMeter(MultiStateTextView.STATE_OK);
        } else if (event.getCommondWord() == CommandWord.readFail[0]) {
            baseView.onCheckLiquidLevelMeter(MultiStateTextView.STATE_ERROR);
        }
        //液位仪是最后一个检测的，检测好就总结一个所有设备的自检情况
        baseView.summaryDeviceSelfCheck();
        baseView.hideLoading();
        if (checkDevice_disposable != null) {
            checkDevice_disposable.dispose();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(CO2BO event) {
        byte commondWord = event.getCommondWord();
        if (commondWord == CommandWord.readSucc[0]) {
            baseView.onCheckCO2(MultiStateTextView.STATE_OK);
        } else if (commondWord == CommandWord.readFail[0]) {
            baseView.onCheckCO2(MultiStateTextView.STATE_ERROR);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(O2BO event) {
        byte commondWord = event.getCommondWord();
        if (commondWord == CommandWord.readSucc[0]) {
            baseView.onCheckO2(MultiStateTextView.STATE_OK);
        } else if (commondWord == CommandWord.readFail[0]) {
            baseView.onCheckO2(MultiStateTextView.STATE_ERROR);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(TemperatureBO event) {
        byte commondWord = event.getCommondWord();
        if (commondWord == CommandWord.readSucc[0]) {
            baseView.onCheckTemperature(MultiStateTextView.STATE_OK);
        } else if (commondWord == CommandWord.readFail[0]) {
            baseView.onCheckTemperature(MultiStateTextView.STATE_ERROR);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(ElectronicScaleBO event) {
        byte commondWord = event.getCommondWord();
        if (commondWord == CommandWord.readSucc[0]) {
            if (isFirstWeight) {
                baseView.onFirstWeight(event.getWeight());
            } else {
                baseView.onCheckWeight(MultiStateTextView.STATE_OK);
            }
        } else if (commondWord == CommandWord.writeSucc[0]) {
            baseView.onInitPeelSucc(event.getAd());
        } else if (commondWord == CommandWord.readFail[0]) {
            if (isFirstWeight) {
                baseView.onFirstWeightFailed();
            } else {
                baseView.onCheckWeight(MultiStateTextView.STATE_ERROR);
            }
        } else {
            baseView.showToast(event.toString());
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(DoorBO event) {
        byte commondWord = event.getCommondWord();
        if (commondWord == CommandWord.readSucc[0]) {
            baseView.onReadDoorSucc(event.getStatusStr());
        } else if (commondWord == CommandWord.writeSucc[0]) {
            if (event.getOrder() == DoorBO.open) {
                baseView.onOpenDoorSucc();
            } else if (event.getOrder() == DoorBO.close) {
                baseView.onCloseDoorSucc();
            }
        } else if (commondWord == CommandWord.readFail[0]) {
            baseView.showToast(event.toString());
        }
    }

    @Override
    public void detachView() {
        EventBus.getDefault().unregister(this);
        if (checkDevice_disposable != null) {
            checkDevice_disposable.dispose();
        }
        if (changeAirSchedule != null) {
            changeAirSchedule.cancel(true);
        }
        super.detachView();
    }
}
